﻿#region Imports
using System;
using System.ComponentModel;
using System.Reflection;
using BulkRenamer.Util.Enums;
#endregion

namespace BulkRenamer.Util.Extensions
{
    /// <summary>
    /// Contains extension methods for Enums
    /// </summary>
    /// <seealso cref="http://stackoverflow.com/questions/1415140/can-my-enums-have-friendly-names" />
    public static class EnumExtensions
    {
        public static string GetEnumDescription(this Enum value)
        {
            Type type = value.GetType();
            string name = Enum.GetName(type, value);

            if (name != null)
            {
                FieldInfo field = type.GetField(name);
                if (field != null)
                {
                    System.Windows.Forms.MessageBox.Show("Use \"GetAttributeProperty\" or \"GetClassDescription<Enum>()\"");

                    DescriptionAttribute attr = Attribute.GetCustomAttribute(field,
                        typeof(DescriptionAttribute)) as DescriptionAttribute;

                    if (attr != null) return attr.Description;
                }
            }

            return "N/A";
        }

        public static string ToString(this Enum e)
        {
            return "(" + e.GetType().Namespace + ") " + e.GetType().FullName.Replace("+", ".").Replace(e.GetType().Namespace, "").Trim('.') + "." + e.ToString();
        }

        //public static Enum EnumFromInt<TEnum>(this Enum e, int value)
        public static TEnum EnumFromInt<TEnum>(int value)
            where TEnum : struct
        {
            try
            {
                if (true) // !Enum.GetValues(typeof(TEnum)).HasValue(0))
                {
                    //return e.GetType().;
                    //.GetValues(typeof(eCopyProperties)).Cast<eCopyProperties>())

                    return (TEnum)Enum.GetValues(typeof(TEnum)).GetValue(value);
                    //return (Enum)Enum.ToObject(typeof(TEnum), value);
                    // //eExtnCase z = (eExtnCase)0; 
                }
                else
                    throw new Exceptions.DefaultValueNotAvailableException(null);
            }
            catch (Exception ex)
            {
                throw new Exceptions.DefaultValueNotAvailableException(ex);
            }
        }

        // RKD : make generic
        //public static Enum GetDefaultValue(this Enum value)
        public static TEnum GetDefaultValue<TEnum>()
            where TEnum : struct
        //    where TEnum : Enumerators
        {
            //GetClassAttribute<Enum, DefaultValueAttribute>();

            //return (Enum) (eCopyProperties.Location.);
            // throw new Exceptions.NoDefaultValueAvailableException();
            // return (TEnum)EnumFromInt<TEnum>(0);

            // OUTPUT : TEnum
            Type t = typeof(TEnum);
            DefaultValueAttribute[] attributes = (DefaultValueAttribute[])t.GetCustomAttributes(typeof(DefaultValueAttribute), false);
            if (attributes != null && attributes.Length > 0)
                return (TEnum)attributes[0].Value;
            else
                return (TEnum)EnumFromInt<TEnum>(0);

            //// OUTPUT : Enum
            //return default(eExtnCase);

            /*
                public enum Status
                {
                    New = 10,
                    Old = 20,
                    Actual = 30,

                    // Use Status.Default to specify default status in your code. 
                    Default = New
                }
            */
        }
    }
}
